package com.future.order.service;

import com.future.order.OrderDO;
import com.future.order.feign.ProductFeignClient;
import com.future.product.ProductDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    protected ProductFeignClient productFeignClient;

    @Override
    public OrderDO create(OrderDO order) {
//        Product product = getProduct(order.getId());
//        Product product = getProductLoadBalance(order.getId());
//        ProductDO product = getProductLoadBalanceAnnotation(order.getId());
        ProductDO product = productFeignClient.getProductId(order.getId(), "token");
        order.setName(order.getName());
        order.setProducts(Collections.singletonList(product));
        return order;
    }


    /**
     * 进阶一
     *
     * @param id
     * @return
     */
    private ProductDO getProduct(Integer id) {
        AtomicInteger atom = new AtomicInteger();
        List<ServiceInstance> instances = discoveryClient.getInstances("service-product");
        int instanceCount = instances.size();
        if (instanceCount == 0) {
            log.error("没有可用的服务");
            return null;
        }
        int index = atom.addAndGet(1) % instanceCount;
        ServiceInstance serviceInstance = instances.get(index);
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/get/" + id;
        return restTemplate.getForObject(url, ProductDO.class);
    }

    /**
     * 进阶二
     *
     * @param id
     * @return
     */
    private ProductDO getProductLoadBalance(Integer id) {
        ServiceInstance instance = loadBalancerClient.choose("service-product");
        if (instance == null) {
            log.error("没有可用的服务");
            return null;
        }
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/product/get/" + id;
        return restTemplate.getForObject(url, ProductDO.class);
    }

    /**
     * 进阶三：基于注解的负载均衡
     * 在restTemplate加了@LoadBalanced
     *
     * @param id
     * @return
     */
    private ProductDO getProductLoadBalanceAnnotation(Integer id) {
        ServiceInstance instance = loadBalancerClient.choose("service-product");
        if (instance == null) {
            log.error("没有可用的服务");
            return null;
        }
        /**
         * service-product会被动态替换
         */
        String url = "http://service-product/product/get/" + id;
        return restTemplate.getForObject(url, ProductDO.class);
    }

}
